/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : main.c
  * @brief          : Main program body
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2025 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "adc.h"
#include "dma.h"
#include "rtc.h"
#include "tim.h"
#include "usart.h"
#include "gpio.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "lcd.h"
#include "stdio.h"
#include "string.h"
#include "i2c_hal.h"
/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */

/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/

/* USER CODE BEGIN PV */
u16 LedData=0xffff;
char buf[30];
u8 Hour,Minute,Second;
u8 RtcHour,RtcMinute,RtcSecond;
vu32 Time50Tick;
vu32 TimeTick;
RTC_TimeTypeDef sfm;//时分秒的RTC的结构变量
RTC_DateTypeDef nyrx;//年月日星期的RTC结构体变量
u8 Trg,Cont,ReadData;
_Bool SCREEN,FLASHFLAG;
vu32 Time500msTick;
u8 B2cou;
vu32 Led100msTick;
u16 LedVal[8]={0xfeff,0xfdff,0xfbff,0xf7ff,0xefff,0xdfff,0xbfff,0x7fff};//灯亮
u8 Ledcou;//循环变量
//串口控制相关定义
u8 rx[3];
u8 rx_buf[30];//上位机向下位机发送字符串长度极限值
u8 rx_cnt;//字符串长度的计数变量
vu32 uartTick;
//ADC采样定义的变量
u32 ADC_Val1[1],ADC_Val2[1];
u32 sum1,sum2;
u8 ADC_cou;
float Vr37,Vr38;
vu32 Time1msTick;
//TIM捕获输入变量
u8 TIM16STATE,TIM3STATE;
u16 TIM16_T1_cnt,TIM16_T2_cnt;
u16 TIM3_T1_cnt,TIM3_T2_cnt;
u16 Freq1,Freq2;
u8 Duty1,Duty2;
/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */
//用户编写函数声明
//对两个外部函数进行声明
extern void x24c02_write(unsigned char address,unsigned char info);
extern unsigned char x24c02_read(uint8_t address);
void Disp1stScreen(void);
void Disp2ndScreen(void);
void ClockRun(void);
void ReadRtcClock(void);
void KeyScan(void);
void LedScan(void);
void LedProcess(void);
void UartProcess(void);
void Write_M24c02_Clock(void);
void Read_M24c02_Clock(void);
void AdcProcess(void);
/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */

/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{

  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_DMA_Init();
  MX_RTC_Init();
  MX_USART1_UART_Init();
  MX_ADC1_Init();
  MX_ADC2_Init();
  MX_TIM2_Init();
  MX_TIM3_Init();
  MX_TIM16_Init();
  MX_TIM17_Init();
  /* USER CODE BEGIN 2 */
 I2CInit();
 Read_M24c02_Clock();
 HAL_UART_Receive_IT(&huart1,rx,1);//启动带中断的串口接受过程
 HAL_ADC_Start_DMA(&hadc1,ADC_Val1,1);
 HAL_ADC_Start_DMA(&hadc2,ADC_Val2,1);
 HAL_TIM_PWM_Start(&htim17,TIM_CHANNEL_1);
 HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_1);
 HAL_TIM_IC_Start_IT(&htim16, TIM_CHANNEL_1);
 HAL_TIM_IC_Start_IT(&htim3, TIM_CHANNEL_2);
 LCD_Init();
 LCD_SetTextColor(White);
 LCD_SetBackColor(Black);
 //LCD_ClearLine(u8 Line);
 LCD_Clear(Black);
 //LCD_DisplayChar(u8 Line, u16 Column, u8 Ascii);
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
		//1ms定时
		if(uwTick-Time1msTick>=1)
		{
			Time1msTick=uwTick;
			AdcProcess();
		}
		//定义systick
		if(uwTick-Time50Tick>=50)
		{
			Time50Tick=uwTick;//为下一秒50毫秒定时做准备
			LedScan();
			KeyScan();
			ReadRtcClock();
			//向M24c02写时分秒
			Write_M24c02_Clock();
		}
		//定时1秒调用时钟走时函数
		if(uwTick-TimeTick>=1000)
		{
			TimeTick=uwTick;
			ClockRun();
			//printf("Clock: %02u-%02u-%02u\r\n",Hour,Minute,Second);
		}
		//500ms定时
		if(uwTick-Time500msTick>=500)
		{
			Time500msTick=uwTick;
			FLASHFLAG=!FLASHFLAG;
			//B1按下切换界面
			if(!SCREEN)
			Disp1stScreen();
			else
			Disp2ndScreen();
		}
		//相关外设处理函数
		LedProcess();
		UartProcess();
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

/**
  * @brief System Clock Configuration
  * @retval None
  */
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  /** Configure the main internal regulator output voltage
  */
  HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1);

  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLM = RCC_PLLM_DIV3;
  RCC_OscInitStruct.PLL.PLLN = 20;
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
  RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2;
  RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }

  /** Initializes the CPU, AHB and APB buses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
  {
    Error_Handler();
  }
}

/* USER CODE BEGIN 4 */
//显示第一屏函数
void Disp1stScreen(void)
{
	LCD_SetTextColor(White);
  LCD_SetBackColor(Black);
	LCD_ClearLine(Line3);//为了ADC转换第二屏切回第一屏无残留
	LCD_ClearLine(Line6);//清理第二屏的PWM和占空比输出
	LCD_ClearLine(Line7);
	//因为要突出显示RTC时钟的数字，所有将第二行和第五行两个时钟程序分开写
	//定义TIM的时钟
	 LCD_DisplayStringLine(Line1, (u8*)"     TIM Clock      ");
	//显示RTC时钟
	 LCD_DisplayStringLine(Line4, (u8*)"     RTC Clock      ");
	//第五行显示"     RTC:"
	LCD_DisplayStringLine(Line5, (u8*)"    RTC:");
	//TIM时钟程序
	if(!FLASHFLAG)
	{
	 sprintf(buf,"   TIM:%02u:%02u:%02u   ",Hour,Minute,Second);
   LCD_DisplayStringLine(Line2,(u8*)buf);
	}
	else
	{
	 sprintf(buf,"   TIM:%02u %02u %02u   ",Hour,Minute,Second);
   LCD_DisplayStringLine(Line2,(u8*)buf);
	}
	//RTC时钟程序，根据B2cou代表的四种状态来分别显示单个字符
	//突出显示第五行时钟数字程序
	if(B2cou==1)//小时矫正模式
	{
		//小时突出显示
		LCD_SetBackColor(Red);
		LCD_DisplayChar(Line5, 320-8*16,RtcHour/10+'0');//320-8*16表示小时的十位数字
		LCD_DisplayChar(Line5, 320-9*16,RtcHour%10+'0');
		LCD_SetBackColor(Black);
		LCD_DisplayChar(Line5, 320-10*16,':');
		LCD_DisplayChar(Line5, 320-11*16,RtcMinute/10+'0');
		LCD_DisplayChar(Line5, 320-12*16,RtcMinute%10+'0');
		LCD_DisplayChar(Line5, 320-13*16,':');
		LCD_DisplayChar(Line5, 320-14*16,RtcSecond/10+'0');
		LCD_DisplayChar(Line5, 320-15*16,RtcSecond%10+'0');
	}
	else if (B2cou==2)//分钟矫正模式
	{
		LCD_SetBackColor(Red);
		LCD_DisplayChar(Line5, 320-11*16,RtcMinute/10+'0');
		LCD_DisplayChar(Line5, 320-12*16,RtcMinute%10+'0');
		LCD_SetBackColor(Black);
		LCD_DisplayChar(Line5, 320-10*16,':');
		LCD_DisplayChar(Line5, 320-8*16,RtcHour/10+'0');
		LCD_DisplayChar(Line5, 320-9*16,RtcHour%10+'0');
		LCD_DisplayChar(Line5, 320-13*16,':');
		LCD_DisplayChar(Line5, 320-14*16,RtcSecond/10+'0');
		LCD_DisplayChar(Line5, 320-15*16,RtcSecond%10+'0');
	}
		else if (B2cou==3)//秒矫正模式
	{
		//小时突出显示
		LCD_SetBackColor(Red);
		LCD_DisplayChar(Line5, 320-14*16,RtcSecond/10+'0');
		LCD_DisplayChar(Line5, 320-15*16,RtcSecond%10+'0');
		LCD_SetBackColor(Black);
		LCD_DisplayChar(Line5, 320-11*16,RtcMinute/10+'0');
		LCD_DisplayChar(Line5, 320-12*16,RtcMinute%10+'0');
		LCD_DisplayChar(Line5, 320-10*16,':');
		LCD_DisplayChar(Line5, 320-8*16,RtcHour/10+'0');
		LCD_DisplayChar(Line5, 320-9*16,RtcHour%10+'0');
		LCD_DisplayChar(Line5, 320-13*16,':');
	}
	else
	{
		LCD_SetBackColor(Black);
		//冒号闪烁
			if(!FLASHFLAG)
			{
				LCD_DisplayChar(Line5, 320-10*16,':');
				LCD_DisplayChar(Line5, 320-13*16,':');
			}
	    else
			{
				LCD_DisplayChar(Line5, 320-10*16,' ');
				LCD_DisplayChar(Line5, 320-13*16,' ');
			}
			//显示时分秒数字
		LCD_DisplayChar(Line5, 320-8*16,RtcHour/10+'0');
		LCD_DisplayChar(Line5, 320-9*16,RtcHour%10+'0');
		LCD_DisplayChar(Line5, 320-11*16,RtcMinute/10+'0');
		LCD_DisplayChar(Line5, 320-12*16,RtcMinute%10+'0');
		LCD_DisplayChar(Line5, 320-14*16,RtcSecond/10+'0');
		LCD_DisplayChar(Line5, 320-15*16,RtcSecond%10+'0');
	}
}
//显示第二屏
void Disp2ndScreen(void)
{
	LCD_SetTextColor(White);
  LCD_SetBackColor(Black);
	LCD_DisplayStringLine(Line1, (u8*)"    ADC Voltage     ");
	LCD_ClearLine(Line2);
	//LCD_ClearLine(Line4);
	LCD_ClearLine(Line5);
	//ADC显示程序
	sprintf(buf," ADC1(PB12)=%1.2f V  ",Vr38);
	LCD_DisplayStringLine(Line3,(u8*)buf);	
	sprintf(buf," ADC2(PB15)=%1.2f V  ",Vr37);
	LCD_DisplayStringLine(Line4,(u8*)buf); 
	//频率和占空比的显示程序
	LCD_SetTextColor(Yellow);
  LCD_SetBackColor(Black);
	sprintf(buf," f1=%5uHz,d1=%2u%%  ",Freq1,Duty1);
	LCD_DisplayStringLine(Line6,(u8*)buf);	
	sprintf(buf," f2=%5uHz,d2=%2u%%  ",Freq2,Duty2);
	LCD_DisplayStringLine(Line7,(u8*)buf); 
}
//时钟走时函数
void ClockRun(void)
{
	if(++Second==60)
	{
		Second=0;
		if(++Minute==60)
		{
			Minute=0;
			if(++Hour==24)
			{
				Hour=0;
			}
		}
	}
}
//读取RTC外设的时钟数据函数
void ReadRtcClock(void)
{
	  // 更新SYSTICK时间
    HAL_RTC_GetTime(&hrtc, &sfm, RTC_FORMAT_BIN);
	  HAL_RTC_GetDate(&hrtc, &nyrx, RTC_FORMAT_BIN);
    RtcHour = sfm.Hours;
    RtcMinute = sfm.Minutes;
    RtcSecond = sfm.Seconds;
}
//键盘扫描函数（含键值处理）
void KeyScan(void)
{
u16 State=0;
u16 BitState=0;
BitState=GPIOB -> IDR;
State=BitState&0x0007;
BitState=GPIOA -> IDR;
State=State|((BitState&0x0001)<<3);
//键盘算法程序（识别键值）
	ReadData=State^0x0f;
	Trg=ReadData&(ReadData^Cont);
	Cont=ReadData;
	//完整键值处理
	if(Trg==0x01)//切换键盘用布尔变量控制（B1键按下后SCREEN变换）
		SCREEN = !SCREEN;
	else if(Trg==0x02)//B2键按下后,按下次数不同有不同的功能，定义B2cou
	{
		if(!SCREEN)
		{
		  if(++B2cou==4)
			B2cou=0;
	  }
	}
		else if(Trg==0x04)//B3键按下后
	{
		if(!SCREEN)
		{
			if(B2cou==1)//小时矫正
			{
        if (++RtcHour == 24)
        RtcHour = 0; 
        sfm.Hours = RtcHour; 
        HAL_RTC_SetTime(&hrtc, &sfm, RTC_FORMAT_BIN);
			}
		  else if(B2cou==2)//分加矫正
			{
				if (++RtcMinute == 60)
        RtcMinute = 0;
        sfm.Minutes = RtcMinute;    
        HAL_RTC_SetTime(&hrtc, &sfm, RTC_FORMAT_BIN);
			}
			else if(B2cou==3)//秒加矫正
			{
				if (++RtcSecond == 60)
        RtcSecond = 0;
        sfm.Seconds = RtcSecond;    
        HAL_RTC_SetTime(&hrtc, &sfm, RTC_FORMAT_BIN);
			}
	 }
}
		else if(Trg==0x08)//B4键按下后,时分秒减矫正
	{
		if(!SCREEN)
		{
			if(B2cou==1)//小时减矫正
			{
        if (--RtcHour == 24)
        RtcHour = 0; 
        sfm.Hours = RtcHour; 
        HAL_RTC_SetTime(&hrtc, &sfm, RTC_FORMAT_BIN);
			}
			else if(B2cou==2)//分减矫正
			{
				if (--RtcMinute == 60)
        RtcMinute = 0;
        sfm.Minutes = RtcMinute;    
        HAL_RTC_SetTime(&hrtc, &sfm, RTC_FORMAT_BIN);
			}
			else if(B2cou==3)//秒减矫正
			{
				if (--RtcSecond == 60)
        RtcSecond = 0;
        sfm.Seconds = RtcSecond;    
        HAL_RTC_SetTime(&hrtc, &sfm, RTC_FORMAT_BIN);
			}
	}
}
	else{;}
}

//LED扫描函数
void LedScan(void)
{
	GPIOC->ODR=LedData;
  HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_SET);
  HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_RESET);
}
//LED处理函数
void LedProcess(void)
{
	//只实现了Ld2的整点报时，还要实现Ld1的
	if((RtcMinute ==59)&&(RtcSecond>=50)&&(RtcSecond<=59))
	{
		if(uwTick-Led100msTick>=100)
	  {
		Led100msTick=uwTick;
			if(++Ledcou>100)
			{
				LedData|=0x0200;//LED2灯灭
				Ledcou=0;//对下一次LED灯的整点报时做准备
			}
			else
		    LedData^=0x0200;//LED2灯闪烁
	  }
	}
	else
		LedData|=0x0200;//LED2灯灭
	// Systick整点报时 (LD1)
    if((Minute ==59)&&(Second>=50)&&(Second<=59))
    {
        static u32 lastToggle = 0;
        if(uwTick - lastToggle >= 500) {
            lastToggle = uwTick;
            LedData ^= 0x0100; // 切换LD1状态
        }
    }
    else {
        LedData |= 0x0100; // LD1熄灭
    }
		    // 电压界面LED控制 
    if(SCREEN) // 电压显示界面
    {
        // 熄灭时钟界面的LED
        LedData |= 0x0300; // LD1和LD2灭 (0x0100 | 0x0200)
        
        // ADC1控制LD3
        static u32 led3Tick = 0;
        if((Vr38 > 1.0f) && (Vr38 < 2.0f)) {
            if(uwTick - led3Tick >= 200) {
                led3Tick = uwTick;
                LedData ^= 0x0400; // LD3闪烁
            }
        } else {
            LedData |= 0x0400; // LD3灭
        }
        
        // ADC2控制LD4
        static u32 led4Tick = 0;
        if((Vr37 > 2.0f) && (Vr37 < 3.0f)) {
            if(uwTick - led4Tick >= 200) {
                led4Tick = uwTick;
                LedData ^= 0x0800; // LD4闪烁
            }
        } else {
            LedData |= 0x0800; // LD4灭
        }
    }
    else // 时钟显示界面
    {
        // 熄灭电压界面的LED
        LedData |= 0x0C00; // LD3和LD4灭 (0x0400 | 0x0800)
    }
}
//printf重定向
int fputc(int ch,FILE *f)
{
	HAL_UART_Transmit(&huart1,(u8*)&ch,1,50);
	return ch;
}
//串口接收中断回调函数
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	uartTick=uwTick;//当上位机向下位机发送字符串，每法送一个字符进一次中断，进终端后开始定时
	rx_buf[rx_cnt++]=rx[0];//将接受到的一个字符保存至rx_buf缓冲数组里面
	HAL_UART_Receive_IT(&huart1,rx,1);//退出中断前，重新启动串口接受中断
}
//串口处理函数
void UartProcess(void)
{
    if(rx_cnt>0)//表示上位机一定在向下位机传送数据
 {
     if(uwTick-uartTick>=50)//超过50ms未接收到上位机传送的字符
   {
		 // 电压查询命令处理
      if(SCREEN) // 仅在电压显示界面响应
         {
          if(strncmp((char*)rx_buf, "ADC1_PB12", 9) == 0)
						{
               printf("ADC1_PB12:%.2f V\r\n", Vr38);
               rx_cnt = 0;
               memset(rx_buf, 0, sizeof(rx_buf));
               return;
             }
           else if(strncmp((char*)rx_buf, "ADC2_PB15", 9) == 0)
						 {
               printf("ADC2_PB15:%.2f V\r\n", Vr37);
               rx_cnt = 0;
               memset(rx_buf, 0, sizeof(rx_buf));
               return;
             }
				}
    if(rx_cnt==4)
    {
            if(rx_buf[0]=='H' && rx_buf[1]=='o'&& rx_buf[2]=='u'&& rx_buf[3]=='+')
      {
                printf("OK1\r\n");    
                if(++Hour==24)Hour=0;
            }
            else if(rx_buf[0]=='H' && rx_buf[1]=='o'&& rx_buf[2]=='u'&& rx_buf[3]=='-'){
            printf("OK2\r\n");    
                if(--Hour==0xff)Hour=23;
            }
						else if(rx_buf[0]=='M' && rx_buf[1]=='i'&& rx_buf[2]=='n'&& rx_buf[3]=='+')
            {
                printf("OK11\r\n");    
                if(++Minute==60)Minute=0;
            }
            else if(rx_buf[0]=='M' && rx_buf[1]=='i'&& rx_buf[2]=='n'&& rx_buf[3]=='-'){
            printf("OK22\r\n");    
                if(--Minute==0xff)Minute=59;
            }
						else if(rx_buf[0]=='S' && rx_buf[1]=='e'&& rx_buf[2]=='c'&& rx_buf[3]=='+')
            {
                printf("OK111\r\n");    
                if(++Second==60)Second=0;
            }
            else if(rx_buf[0]=='S' && rx_buf[1]=='e'&& rx_buf[2]=='c'&& rx_buf[3]=='-'){
            printf("OK222\r\n");    
                if(--Second==0xff)Second=59;
            }
						else
            printf("OK3\r\n");
    }
    else 
      printf("ERROR\r\n");    
      //恢复到串口接收一个字符或字符串之前的状态
						rx_cnt=0;
						memset(rx_buf,'\0',sizeof(rx_buf));
   }
 }
}
//向M24c02写入时钟数据
void Write_M24c02_Clock(void)
{
			x24c02_write(0,Hour);
			x24c02_write(1,Minute);
			x24c02_write(2,Second);
}
//从M24c02读出时钟数据
void Read_M24c02_Clock(void)
{
	if(x24c02_read(100)==0x55)
	{
		Hour=x24c02_read(0);
		Minute=x24c02_read(1);
		Second=x24c02_read(2);
	}
	else
	{
		x24c02_write(100,0x55);//给100号地址输入密码0x55，同时给时分秒数据初值
		Hour=13;
		Minute=13;
		Second=13;
	}

}
//ADC采样程序
void AdcProcess(void)//每一毫秒调用此函数一次，每100毫秒
{
	//采样ADC1,ADC2
	sum1+=ADC_Val1[0];
	sum2+=ADC_Val2[0];
	if(++ADC_cou==100)
	{
		ADC_cou=0;
		Vr38=(3.3/4095)*(sum1/100);//sum1/100求均值，又叫均值滤波
		Vr37=(3.3/4095)*(sum2/100);	
		//根据vr37,vr38的数值来改变占空比
		TIM17->CCR1 = 10*sum2/4095;
		TIM2->CCR1 = sum1/4095;
		sum1=0;sum2=0;
	}
}

//定时器捕获中断回调函数
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
	//测量PA7输出的PWM波的频率和占空比
	if(htim==&htim16)
	{
			if(TIM16STATE==0)   //初始化时设置上升沿触发后第1次进中断
		{
			__HAL_TIM_SetCounter(&htim16,0);
			TIM16->CCER |= 0x0002; 
			TIM16STATE=1;
		}
		else if(TIM16STATE==1)                          
		{
				TIM16_T1_cnt = __HAL_TIM_GET_COUNTER(&htim16);  
				TIM16->CCER &= 0xfffd;                         
				TIM16STATE=2;                                  
		}
		else                                            
		{
				TIM16_T2_cnt = __HAL_TIM_GET_COUNTER(&htim16);  
				Freq1 = 1000000/TIM16_T2_cnt;                    
				Duty1=TIM16_T1_cnt*100/TIM16_T2_cnt;         
				TIM16STATE=0;                                  
		}
		HAL_TIM_IC_Start_IT(&htim16, TIM_CHANNEL_1);
  }
	//测量PA5输出的PWM波的频率和占空比
	else if(htim==&htim3)
	{
			if(TIM3STATE==0)   //初始化时设置上升沿触发后第1次进中断
		{
			__HAL_TIM_SetCounter(&htim3,0);
			TIM3->CCER |= 0x0020; 
			TIM3STATE=1;
		}
		else if(TIM3STATE==1)                          
		{
				TIM3_T1_cnt = __HAL_TIM_GET_COUNTER(&htim3);  
				TIM3->CCER &= 0xffdf;                         
				TIM3STATE=2;                                  
		}
		else                                            
		{
				TIM3_T2_cnt = __HAL_TIM_GET_COUNTER(&htim3);  
				Freq2 = 1000000/TIM3_T2_cnt;                    
				Duty2=TIM3_T1_cnt*100/TIM3_T2_cnt;         
				TIM3STATE=0;                                  
		}
		HAL_TIM_IC_Start_IT(&htim3, TIM_CHANNEL_2);
  }
	else {;}
}
/* USER CODE END 4 */

/**
  * @brief  This function is executed in case of error occurrence.
  * @retval None
  */
void Error_Handler(void)
{
  /* USER CODE BEGIN Error_Handler_Debug */
  /* User can add his own implementation to report the HAL error return state */
  __disable_irq();
  while (1)
  {
  }
  /* USER CODE END Error_Handler_Debug */
}

#ifdef  USE_FULL_ASSERT
/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t *file, uint32_t line)
{
  /* USER CODE BEGIN 6 */
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  /* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */

